/*
Copyright (c) 2013, trixpro.com, Inc.
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice, 
    this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, 
    this list of condit
    and/or other materials provided with the distribution.
    * Neither the name of the trixpro.com, Inc. nor the names of its contributors 
    may be used to endorse or promote products derived from this software 
    without specific prior written permission.


THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
OF THE POSSIBILITY OF SUCH DAMAGE.
*/

global class Utils {
	public class MakeSqlException extends Exception {}
	/**
	* MakeSelectSql 
	* return "select * from Object"
	*/
	public static string MakeSelectSql(Schema.DescribeSObjectResult DescSobject){
		string sqlStr = '';
		Map<String, Schema.SObjectField> fieldsmap = DescSobject.fields.getMap();
    for (String fName : fieldsmap.keySet()){
        sqlstr = sqlstr + fName+',';
    }
    if(sqlstr.length()>0){
        sqlstr = sqlstr.substring(0,sqlstr.length()-1);
    }
    sqlstr = 'select '+sqlstr+' from '+ DescSobject.name;
 		//limit check
 		if(sqlstr.length()== 0) throw new MakeSqlException('The Object not exist'); 
 		if(sqlstr.length()> 10000) throw new MakeSqlException('sql length over 10000'); 
		return sqlStr;
	}
	/**
	* GetObjByID
	* return [select * from Object where id=:id]
	*/
	public static sObject GetObjByID(Schema.DescribeSObjectResult DescSobject,string id){
        return Database.query(MakeSelectSql(DescSobject)+' Where id =:id');
	}
	
  public static String makeUrlStr(String pValue){
  	String sRtn = '';
  	if (pValue != null){
  		sRtn = system.Encodingutil.urlEncode(pValue, 'UTF-8');
  	}  	
  	return sRtn;
  }
  
  /*
  *
  * get picklist default value
  */
	public static String getPicklistDefaultValue(Schema.DescribeSObjectResult objDesc, String fieldName){
		String sDefaultValue = '';
  	try{
	    Map<String, Schema.SObjectField> fieldsMap = objDesc.fields.getMap();
	    List<Schema.PicklistEntry> pickListValues = fieldsMap.get(fieldName).getDescribe().getPickListValues();
	    for (Schema.PicklistEntry item : pickListValues){
	    	if (item.isDefaultValue()){
	    		sDefaultValue = item.getValue();
	    		break;
	    	}
	    }
  	}catch(Exception ex){
  		
  	}
  	return sDefaultValue;
	}
	
  /*
  *
  * get picklist value
  */
	public static List<String> getPicklistValue(Schema.SObjectField field){
		List<String> sValue = new List<String>();
	  	try{
		    List<Schema.PicklistEntry> pickListValues = field.getDescribe().getPickListValues();
		    for (Schema.PicklistEntry item : pickListValues){
		    	sValue.add(item.getValue());
		    }
	  	}catch(Exception ex){
	  		
	  	}
  		return sValue;
	}
	
  /*
  *get page parameter
  */
  public static String getPageParam(String pParamName){
  	String sValue;
  	try{
  		sValue = ApexPages.currentPage().getParameters().get(pParamName);
  		if (sValue != null){
  			sValue = system.Encodingutil.urlDecode(sValue, 'UTF-8');
  		}
  	}catch(Exception ex){
  		sValue = '';
  	}
  	return sValue;
  }
  
  /*
  *set page parameter
  */
  public static Boolean putPageParam(PageReference pRef, String pName, String pValue){
  	Boolean bRtn = false;
  	String sValue;
  	try{
  		sValue = system.Encodingutil.urlEncode(pValue, 'UTF-8');
  		pRef.getParameters().put(pName, sValue);
  	}catch(Exception ex){
  		return bRtn;
  	}
  	bRtn = true;
  	return bRtn;
  }
  	//send mail with attachments id
    global static void sendEmailWithStandardAttachments(List<String> recipients,String emailSubject,String body,Boolean useHTML,List<Id> attachmentIDs) {
        List<Attachment> stdAttachments = [SELECT id, name, body FROM Attachment WHERE Id IN:attachmentIDs];
        sendEmailWithStandardAttachments(recipients, emailSubject, body, useHTML, stdAttachments);
    }
    //send mail with attachments
    global static void sendEmailWithStandardAttachments(List<String> recipients,String emailSubject,String body,Boolean useHTML,List<Attachment> stdAttachments) {
        List<Messaging.EmailFileAttachment> fileAttachments = new List<Messaging.EmailFileAttachment>();
        
        for(Attachment attachment : stdAttachments) {
            Messaging.EmailFileAttachment fileAttachment = new Messaging.EmailFileAttachment();
            fileAttachment.setFileName(attachment.Name);
            fileAttachment.setBody(attachment.Body);
            fileAttachments.add(fileAttachment);
        }
        sendEmail(recipients, emailSubject, body, useHTML, fileAttachments);
    }
    //send text mail
    global static void sendTextEmail(List<String> recipients,String emailSubject,String textBody) { 
        sendEmail(recipients, emailSubject, textBody, false, null);
    }
    //send html mail
    global static void sendHTMLEmail(List<String> recipients,String emailSubject,String htmlBody) { 
        sendEmail(recipients, emailSubject, htmlBody, true, null);
    }
    //send mail
    global static void sendEmail(List<String> recipients,String emailSubject,String body,Boolean useHTML,List<Messaging.EmailFileAttachment> fileAttachments) { 
        if(recipients == null) return;
        if(recipients.size() == 0) return;
        // Create a new single email message object
        // that will send out a single email to the addresses in the To, CC & BCC list.
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();        
        //the email is not saved as an activity.
        mail.setSaveAsActivity(false);
        // Assign the addresses for the To lists to the mail object.
        mail.setToAddresses(recipients);          
        // Specify the subject line for your email address.
        mail.setSubject(emailSubject);
        // Set to True if you want to BCC yourself on the email.
        mail.setBccSender(false);
        // The email address of the user executing the Apex Code will be used.
        mail.setUseSignature(false);
        if (useHTML) {
            // Specify the html content of the email.
            mail.setHtmlBody(body);
        } else {
            // Specify the text content of the email.
            mail.setPlainTextBody(body);
        }
        // Specify FileAttachments
        if(fileAttachments != null && fileAttachments.size() > 0) {
            mail.setFileAttachments(fileAttachments);
        }
        // Send the email you have created.
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
    }
    
    global static  List<List<String>> parseCSV(String contents,Boolean skipHeaders) {
			List<List<String>> allFields = new List<List<String>>();
	
			// replace instances where a double quote begins a field containing a comma
			// in this case you get a double quote followed by a doubled double quote
			// do this for beginning and end of a field
			contents = contents.replaceAll(',"""',',"DBLQT').replaceall('""",','DBLQT",');
			// now replace all remaining double quotes - we do this so that we can reconstruct
			// fields with commas inside assuming they begin and end with a double quote
			contents = contents.replaceAll('""','DBLQT');
			// we are not attempting to handle fields with a newline inside of them
			// so, split on newline to get the spreadsheet rows
			List<String> lines = new List<String>();
			try {
				lines = contents.split('\n');
			} catch (System.ListException e) {
				System.debug('Limits exceeded?' + e.getMessage());
			}
			Integer num = 0;
			for(String line : lines) {
				// check for blank CSV lines (only commas)
				if (line.replaceAll(',','').trim().length() == 0) break;
				
				List<String> fields = line.split(',');	
				List<String> cleanFields = new List<String>();
				String compositeField;
				Boolean makeCompositeField = false;
				for(String field : fields) {
					if (field.startsWith('"') && field.endsWith('"')) {
						cleanFields.add(field.replaceAll('DBLQT','"'));
					} else if (field.startsWith('"')) {
						makeCompositeField = true;
						compositeField = field;
					} else if (field.endsWith('"')) {
						compositeField += ',' + field;
						cleanFields.add(compositeField.replaceAll('DBLQT','"'));
						makeCompositeField = false;
					} else if (makeCompositeField) {
						compositeField +=  ',' + field;
					} else {
						cleanFields.add(field.replaceAll('DBLQT','"'));
					}
				}
				
				allFields.add(cleanFields);
			}
			if (skipHeaders) allFields.remove(0);
			return allFields;		
		}
}